import __tool__             from '../tool/index.js';
import __canvas__           from '../canvas/index.js';
import __formate__          from '../formate/index.js';
import __formateHawkEye__   from '../formate/hawkEye.js';
import __node__             from '../node/index.js';
import __line__             from '../line/index.js';
import __opt__              from '../opt/index.js';
import __customEvent__      from '../customEvent/index.js';

class dataClass {
    constructor(){
        this.nodes          = [];           // 节点集
        this.direction      = "level";      // 图谱方向
        this.edit           = true;         // 编辑状态
        this.publicData     = {};           // 公共数据
        this.nodesManyIds   = {};           // 节点的子节点ID列表

        this.nodeCheck      = '';           // 节点单选        
        this.nodeCheckbox   = {             // 节点多选
            is:false,
            items:[],
        };
    }

    // 设置单值
    set(name,val=null){
        if(!name || typeof name !== "string"){
            console.error('set入参不规范');
            return;
        }

        let nodes   = this.nodes;
        let has     = this.has(name);

        val = __tool__.deepCopy(val);
        if(has){
            for(let k in nodes){
                if(nodes[k].id === name){
                    nodes[k] = val;
                    break;
                }
            }
        }
        else{
            nodes.push(val);
        }
        
    }

    // 获取单值
    get(name){
        let nodes = this.nodes.filter(item=>{
            item.childrenIds = this.nodesManyIds[item.id];
            return item.id === name;
        });

        return nodes.length > 0?nodes[0]:null;
    }

    // 更新单值
    /*
        update(name,newNode)
            name:节点ID
            newNode:新节点
            hasEvt:是否有监听事件

        可更新属性
        label       : 标题
        nodeType    : 逻辑类型
        priority    : 优先级
        status      : 节点状态
        html        : 自定义额外内容
        nodeLimit   : 节点宽度
        color       : 自定义字体颜色
        bgColor     : 自定义背景字体颜色
    */
    update(name,newNode,hasEvt){
        if(!name)return;
        let oldNode = null;
        for(let el of this.nodes){
            if(el.id === name){
                oldNode = el;
                break;
            }
        }
        if(!oldNode)return;
        
        let fnNames = [
            'label',
            'nodeType',
            'priority',
            'status',
            'html',
            'nodeLimit',
            'divClass',
            'divColor',
            'divBgColor',
            'gruop',
        ];

        let fn = {
            label:(val)=>{
                oldNode.label = val;
            },
            nodeType:(val)=>{
                oldNode.nodeType = val; 
            },
            priority:(val)=>{
                oldNode.priority = val; 
            },
            status:(val)=>{
                oldNode.status = val; 
            },
            html:(val)=>{
                oldNode.html = val; 
            },
            nodeLimit:(val)=>{
                oldNode.nodeLimit = val; 
            },
            divClass:(val)=>{
                oldNode.divClass = val;
            },
            divColor:(val)=>{
                oldNode.divColor = val;
            },
            divBgColor:(val)=>{
                oldNode.divBgColor = val;
            }
        }

        let sign = true;
        for(let k in newNode){
            if(fnNames.includes(k)){
                sign = false;
                fn[k](newNode[k]);
            }
        }

        if(!sign){
            this.setNodes(this.nodes);

            if(!hasEvt)return;
            // 绑定自定义事件
            __customEvent__.set({
                type:"nodeUpdata",
                data:{}
            });
        }
    }

    // 判断是否有此数据
    has(name){
        let nodes = this.nodes.filter(item=>{
            return item.id === name;
        });

        return nodes.length>0;
    }

    // 删除某一项
    del(name){
        let sign = false;
        let nodes = this.nodes.filter(item=>{
            if(item.id === name)sign=true;
            return item.id !== name;
        });

        this.nodes = nodes;
        return sign;
    }

    // 交换位置
    changeIndex(id1,id2,type){
        let nodes = this.nodes;

        let id1_i = 0,
            id2_i = 0;

        let insertData = this.get(id1);
        
        for(let k in nodes){
            let el = nodes[k];
            if(el.id === id1)id1_i=k;
            if(el.id === id2)id2_i=k;
        }

        if(type === "up"){
            let i = id2_i > id1_i?id2_i-1:id2_i;
            nodes.splice(id1_i,1);
            nodes.splice(i,0,insertData)
            return;
        }

        if(type === "down"){
            let i = id2_i < id1_i?id2_i+1:id2_i;
            nodes.splice(id1_i,1);
            nodes.splice(i,0,insertData)
            return;
        }
    }

    // 清除数据
    clear(){
        this.nodes = [];
    }

    // 获取数据
    getAllNodes(){
        return __tool__.deepCopy(this.nodes);
    }

    // 重置数据
    setNodes(data){
        if(!data){
            console.error('setNodes入参不规范');
            return;
        }
        
        this.clear();

        for(let k in data){
            let val = __tool__.deepCopy(data[k]);

            val = __formate__.nodeDataModel(val);
            val.node.index = k;

            this.nodes.push(val);
        }

        this.loadInit();// 加载初始化数据
    }

    // 设置根节点数据
    setRootData(res){
        let rootData = this.get('root');
        rootData = {...rootData,...res}
        // rootData.nodeGroup = res.nodeGroup;
        this.update('nodeGroup',rootData,false);
    }

    // 加载初始化数据
    loadInit(){
        __canvas__.reset({nodes:this.nodes});   // 视图层-初始化
        __formate__.init(this.nodes);           // 数据层-初始化
        __formateHawkEye__.init(this.nodes);    // 鹰眼-初始化
        __node__.init();                        // 初始化节点
        __line__.use();                         // 使用线路
        setTimeout(()=>{
            __opt__.init();                     // 其它事件的初始化
        });
    }

    // 重新渲染
    reset(){
        let nodes = this.getAllNodes();

        nodes.forEach(el=>{
            el.childrenIds = this.nodesManyIds[el.id];
        })
        this.setNodes(nodes);
    }
}

let data = new dataClass();
export default data;